package com.doublefish.doublefishrobot.utils.socket;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSpecifier;
import android.os.Build;
import android.os.Handler;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

import com.doublefish.doublefishrobot.R;
import com.doublefish.doublefishrobot.ui.home.bean.DeviceBean;
import com.doublefish.doublefishrobot.utils.ble.bean.ModeConstant;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;


/**
 * 作者:dugaofeng on 2025/1/9 16:25
 */
public class SocketManager {

    private boolean didInitSocketManager = false;

    private static String S5_WIFI_PREFIX = "DF-S5-";
    private static String S3_WIFI_PREFIX = "DF-S3-";

    private static String WIFI_PWD = "df888888";

    private Context context;
    private static volatile SocketManager instance;

    // 创建一个socket
    private SocketClient socketClient = new SocketClient();

    private DeviceBean curDeviceBean;

    private OnScanWifiCallback onScanWifiCallback;
    private int scanDeviveType; // 扫码时的设备类型

    private BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            boolean success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
            if (onScanWifiCallback == null) {
                return;
            }
            if (success) {
                handleScanResults();
            } else {
                onScanWifiCallback.onScanResults(false, null);
            }
        }
    };

    public static SocketManager getInstance() {
        if (instance == null) {
            synchronized (SocketManager.class) {
                if (instance == null) {
                    instance = new SocketManager();
                }
            }
        }
        return instance;
    }

    private SocketManager() {

    }

    public void init(Context context) {
        if (didInitSocketManager) {
            return;
        }
        this.context = context;
        context.registerReceiver(wifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        didInitSocketManager = true;

        socketClient.setContext(context);
    }

    public void setBackground(boolean background) {
        socketClient.setBackground(background);
    }

    //后台播放音频
    public void playSilentMp3IfNeeded() {
        socketClient.playSilentMp3IfNeeded();
    }
    //停止音频
    public void stopSilentMp3IfNeeded() {
        socketClient.stopSilentMp3IfNeeded();
    }

    //是否已连接
    public boolean didConnected() {
        return socketClient.didConnected();
    }

    public DeviceBean getCurDeviceBean() {
        return curDeviceBean;
    }

    //region WIFI相关
    public boolean isWifiEnabled() {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }
        return wifiManager.isWifiEnabled();
    }

    public WifiInfo getWifiInfo() {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        return wifiManager.getConnectionInfo(); //过期了 但是可以用
    }

    public void scanWifi(int deviceType, OnScanWifiCallback onScanWifiCallback) {
        if (onScanWifiCallback == null) {
            return;
        }
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            onScanWifiCallback.onScanResults(false, null);
            return;
        }
        this.scanDeviveType = deviceType;
        this.onScanWifiCallback = onScanWifiCallback;

        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        //开始刷新WIFI列表
        if (wifiManager.startScan()) {
           //等待刷新 监听广播的回调
        } else {
            onScanWifiCallback.onScanResults(false, null);
        }
    }

    private void handleScanResults() {
        if (onScanWifiCallback == null) {
            return;
        }
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            onScanWifiCallback.onScanResults(false, null);
            return;
        }

        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        List<ScanResult> scanResults = wifiManager.getScanResults();
        if (scanResults == null || scanResults.size() == 0) {
            onScanWifiCallback.onScanResults(false, null);
            return;
        }
        List<DeviceBean> deviceBeans = new ArrayList<>();
        for (ScanResult result : scanResults) {
            String ssid = result.SSID;
            if (scanDeviveType == ModeConstant.DeviceTypeS5 && ssid.startsWith(S5_WIFI_PREFIX)) {
                DeviceBean deviceBean = new DeviceBean();
                deviceBean.setDeviceType(ModeConstant.DeviceTypeS5);
                deviceBean.setName(result.SSID);
                deviceBeans.add(deviceBean);
            }
            if (scanDeviveType == ModeConstant.DeviceTypeS3 && ssid.startsWith(S3_WIFI_PREFIX)) {
                DeviceBean deviceBean = new DeviceBean();
                deviceBean.setDeviceType(ModeConstant.DeviceTypeS3);
                deviceBean.setName(result.SSID);
                deviceBeans.add(deviceBean);
            }
        }
        onScanWifiCallback.onScanResults(true, deviceBeans);
    }

    public void connectDevice(DeviceBean bindBean, OnDeviceConnectListner onDeviceConnectListner) {
        //先判断WiFi
        if (bindBean.getName() == null || bindBean.getName().length() == 0) {
            if (onDeviceConnectListner != null) {
                onDeviceConnectListner.onConnect(false, context.getString(R.string.devic_name_err));
            }
            return;
        }
        this.curDeviceBean = bindBean;

        // socket的回调
        OnSocketConnectListner onSocketConnectListner = new OnSocketConnectListner() {
            @Override
            public void onConnect(boolean suc) {
                if (onDeviceConnectListner != null) {
                    onDeviceConnectListner.onConnect(suc, suc ? context.getString(R.string.success_connect) : context.getString(R.string.fail_connect));
                }
            }
        };
        //WiFi的回调
        OnWifiConnectListner onWifiConnectListner = new OnWifiConnectListner() {
            @Override
            public void onConnect(boolean suc, String msg) {
                if (suc) {
                    if (onDeviceConnectListner != null) {
                        onDeviceConnectListner.willConnectSocket();
                    }
                    //继续连接socket
                    connectSockt(onSocketConnectListner);
                } else {
                    if (onDeviceConnectListner != null) {
                        onDeviceConnectListner.onConnect(false, context.getString(R.string.failed_connect_hotspot));
                    }
                }
            }
        };

        //判断当前wifi
        WifiInfo wifiInfo = getWifiInfo();
        String ssid = wifiInfo.getSSID();
        if (ssid != null) {
            ssid = ssid.replace("\"", "");
        }
        if (ssid == null || ssid.length() == 0) {
            connectWiFi(bindBean.getName(), onWifiConnectListner);
            return;
        }
        if (ssid.equals(bindBean.getName())) {
            //同一个wifi 直接连接socket
            if (onDeviceConnectListner != null) {
                onDeviceConnectListner.willConnectSocket();
            }
            connectSockt(onSocketConnectListner);
        } else {
            //不同的WiFi 先连接WiFi
            connectWiFi(bindBean.getName(), onWifiConnectListner);
        }
    }

    private String netId = "";
    private void connectWiFi(String wifi, OnWifiConnectListner onWifiConnectListner) {
        if (wifi == null || (!wifi.startsWith(S5_WIFI_PREFIX) && !wifi.startsWith(S3_WIFI_PREFIX))) {
            if (onWifiConnectListner != null) {
                onWifiConnectListner.onConnect(false, context.getString(R.string.wifi_err));
            }
            return;
        }
        String ssid = wifi;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkRequest networkRequest = new NetworkRequest.Builder()
                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
//                    .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                    .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
                    .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)

                    .setNetworkSpecifier(new WifiNetworkSpecifier.Builder()
                            .setSsid(ssid)
                            .setWpa2Passphrase(WIFI_PWD)
                            .build())
                    .build();

            connectivityManager.requestNetwork(networkRequest, new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    super.onAvailable(network);
                    if (netId.equals(network.toString())) {
                        return;
                    }
                    netId = network.toString();
                    // 成功连接到指定的WiFi网络
                    connectivityManager.bindProcessToNetwork(network);

                    if (onWifiConnectListner != null) {
//                        onWifiConnectListner.onConnect(true, null);
                        //第一次连接wif后， 马上连接socket会链接失败。 做一个延迟
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                onWifiConnectListner.onConnect(true, null);
                            }
                        }, 1000);
                    }
                }

                // 其他回调方法，如onLost()等，可以根据需要重写
                @Override
                public void onLost(@NonNull Network network) {
                    super.onLost(network);
                    connectivityManager.bindProcessToNetwork(null);

                    //注释掉 直接断网 这里会闪退
//                    if (onWifiConnectListner != null) {
//                        onWifiConnectListner.onConnect(false, "连接WiFi失败");
//                    }
                }

                @Override
                public void onUnavailable() {
                    super.onUnavailable();
                    if (onWifiConnectListner != null) {
                        onWifiConnectListner.onConnect(false, context.getString(R.string.failed_connect_hotspot));
                    }
                }
            }, 5000);
        } else {
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            // 检查WiFi是否已启用，如果没有则启用它
            if (!wifiManager.isWifiEnabled()) {
                wifiManager.setWifiEnabled(true);
            }

            WifiConfiguration configuration = new WifiConfiguration();
            configuration.SSID = "\"" + ssid + "\"";
            configuration.preSharedKey = "\"" + WIFI_PWD + "\"";

            // 设置安全类型（这里以WPA2为例）
            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // 对于WPA2
            configuration.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // 对于WPA
            configuration.allowedAuthAlgorithms.clear();
            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN); // 对于WPA/WPA2 PSK
            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP); // 对于WPA2
            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP); // 对于WPA
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

            int netId = wifiManager.addNetwork(configuration);
            if (netId != -1) {
                wifiManager.disconnect();
                wifiManager.enableNetwork(netId, true);
                wifiManager.reconnect();
                if (onWifiConnectListner != null) {
                    onWifiConnectListner.onConnect(true, null);
                }
            } else {
                if (onWifiConnectListner != null) {
                    onWifiConnectListner.onConnect(false, context.getString(R.string.failed_connect_hotspot));
                }
            }
        }
    }


    //endregion

    //region  socket相关

    //连接socket 用于发球
    public void connectSockt(OnSocketConnectListner onConnectListner) {
        socketClient.connectToSocket(new OnSocketConnectListner() {
            @Override
            public void onConnect(boolean suc) {
                if (suc) {
                   //监听回调数据
                    socketClient.startReceiveData();
                    startHeartBeatTimer();
                } else {
                    stopHeartBeatTimer();
                }
                if (onConnectListner != null) {
                    onConnectListner.onConnect(suc);
                }
            }
        });
    }

    //断开socket
    public void setOnDisConnectListner(SocketManager.OnSocketDisConnectListner onDisConnectListner) {
        if (socketClient != null) {
            socketClient.setOnDisConnectListner(onDisConnectListner);
        }
    }
    public void disConnectSocket() {
        if (socketClient != null) {
            socketClient.disConnectSocket();
        }
    }

    //在 '发球页面'开始时调用
    public void setOnSocketBallCountListner(OnSocketBallCountListner onSocketBallCountListner) {
        socketClient.setOnSocketBallCountListner(onSocketBallCountListner);
    }

    public void sendData(char[] data) {
        heartTime = 0;
        socketClient.sendSocketData(data);
    }
    //endregion


    //region 定时器
    private Timer timer = null;
    private int heartTime = 0;
    private void startHeartBeatTimer() {
        if (timer != null) {
            return;
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                timerAction();
            }
        }, 1000, 1000);
    }

    private void stopHeartBeatTimer() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    //心跳时间 后台是10秒 app4秒发一条数据
    private void timerAction() {
        heartTime++;
        if (heartTime >= 4) {
            heartTime = 0;
            sendHeartBeatData();
        }
        //监听连接状态
        socketClient.listnerConnectState();
    }

    private void sendHeartBeatData() {
        char[] data = DFS5ProtocolMaker.heartBeat();
        sendData(data);
    }

    //endregion

    //region  interface
    public interface OnScanWifiCallback {
        void onScanResults(boolean suc, List<DeviceBean> list);
    }

    public interface OnDeviceConnectListner {
        void willConnectSocket(); //将要连接socket
        void onConnect(boolean suc, String msg);
    }

    public interface OnWifiConnectAndGetInfoListner {
        void onConnect(boolean suc);
    }

    public interface OnWifiConnectListner {
        void onConnect(boolean suc, String msg);
    }

    public interface OnSocketConnectListner {
        void onConnect(boolean suc);
    }

    public interface OnSocketDisConnectListner {
        void onDisConnect();
    }

    public interface OnSocketBallCountListner {
        void onBallCount(int count);
    }

    //endregion
}
